iT邦幫忙

2024 iThome 鐵人賽

DAY 4
0
Security

你的程式真的安全嗎?從資安的角度做 code review系列 第 4

C - double free (記憶體損壞:雙重釋放)

  • 分享至 

  • xImage
  •  

終於進到我們的主軸程式碼安全的部分啦~我這次是選擇C語言做為練習,就讓我們一起學習吧!

下方程式碼片段全部都是擷取自 Secure Code Warrior 線上安全程式培訓平台,因為練習互動時的題目多半不會只有單一個檔案,可能涉及多個檔案、資料夾及多處地方修改,因此我的文章主要是針對最主要的區塊做修改及說明,若有程式上不好理解的地方非常抱歉也還請見諒,也可以實際上去 Secure Code Warrior 玩玩看,搭配著互動,會更有感的學習哦~

C - double free (記憶體損壞:雙重釋放)

  • 形成原因:同一個記憶體位置上多次呼叫free()函數

  • 後果:使程式執行產生混亂,讓攻擊者能覆寫或執行任意程式碼

  • 在哪出現:任何呼叫釋放的地方,free()函數將之前calloc(), malloc()realloc()分配記憶體的地方解除分配

  • 實例:

    攻擊者發送了一個包含多個 free()函數調用的 GIF 文件。當用戶點擊這個 GIF 時,會觸發漏洞。這個 GIF 使用一個名為 rasterbits 的緩衝區來儲存圖像數據,並且多個已編碼的影格(frame)共用這個緩衝區。

    但是,當 rasterbits 符合以下三個條件之一時,該緩衝區會被釋放:
    1. width * height 大於 originalWidth * originalHeight
    2. width - originalWidth > 0
    3. height - originalHeight > 0

    如果重新分配(re-allocation)的大小設為 0,則會導致 re-allocation(0) 等同於 free(),從而釋放記憶體。然而,攻擊者將重新分配的大小設置為 100, 0, 0,這樣的操作會導致系統錯誤地釋放同一塊記憶體兩次,從而觸發雙重釋放的漏洞,進一步可能被攻擊者利用來攻擊系統。

    • 如何防止:
      • 確保每個分配只能釋放一次
      • 釋放區塊後,將指標設定為NULL

第一題

錯誤區塊

Database::~Database() {
	delete this->db;
}
//程式碼片段擷取自 Secure Code Warrior 線上安全程式培訓平台

解釋:Database類別指向SQLite::Database 類別物件的指標。此指標未在此類別中初始化,也不由建構函式填寫。刪除未初始化的指標是未定義的行為。

主要修正方法

把此區塊刪除:

void Database::checkDatabase() {
	db = new SQLite::Database(
		/* DB path */ db_filename,
		/* DB flags */ SQLite::OPEN_CREATE | SQLite::OPEN_READWRITE
	);
}
//程式碼片段擷取自 Secure Code Warrior 線上安全程式培訓平台

及刪除此段程式碼:

delete this->db;
//程式碼片段擷取自 Secure Code Warrior 線上安全程式培訓平台

並在底下修正:

Database::Database(std::string& db_filename, User& user):
    db_filename(db_filename),
    user(user)
{
	this->db = std::make_unique<SQLite::Database>(
			/* DB path */ db_filename,
			/* DB flags */ SQLite::OPEN_CREATE | SQLite::OPEN_READWRITE
	);
}
//程式碼片段擷取自 Secure Code Warrior 線上安全程式培訓平台

解釋:
Std::unique_ptr自動管理指向已建立物件的指標。當該物件超出範圍時,它會自動刪除。


上一篇
在正式開始之前你要了解的東西:OWASP
下一篇
C - null deference (記憶體損壞:空指標引用)
系列文
你的程式真的安全嗎?從資安的角度做 code review25
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言